/*
    pg_shutdown.c
        Follow the user's mode and quit the PostgreSQL
    Wen Yi
*/
#include "postgres.h"
#include "utils/elog.h"
#include "miscadmin.h"
#include "funcapi.h"
#include "utils/builtins.h"
#include <signal.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <ctype.h>

#define HELP_MESSAGE "Usage:  select pg_shutdown('mode');  \n" \
                     "\tmode could be:  \n" \
                     "\th: Help mode.  \n" \ 
                     "\ts: Smart Shutdown mode.  \n" \
                     "\tf: Fast Shutdown mode.  \n" \
                     "\ti: Immediate Shutdown mode.  \n"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(pg_shutdown);

Datum pg_shutdown(PG_FUNCTION_ARGS)
{
    sigset_t set, backup_set;
    int sig = -1;
    char *mode;
    if (PG_NARGS() == 0)
    {
        PG_RETURN_CSTRING(HELP_MESSAGE);   
    }
    mode = PG_GETARG_CSTRING(0);
    switch (tolower(*mode))
    {
        case 's': /* Smart Shutdown mode */
            sig = SIGTERM;
            break;
        case 'f': /* Fast Shutdown mode */
            sig = SIGINT;
            break;
        case 'i': /* Immediate Shutdown mode */
            sig = SIGQUIT;
            break;
        case 'h':
        default:
            PG_RETURN_CSTRING(HELP_MESSAGE);
            break;
    }
    sigaddset(&set, sig);
    sigprocmask(SIG_UNBLOCK, &set, &backup_set);
    kill(PostmasterPid, sig);
    PG_RETURN_NULL();
}